package com.mysoft.gfyx.workbench.service.AuthenticationProcessor;

import com.mysoft.framework.cache.api.CacheProvider;
import com.mysoft.framework.common.constant.HeaderConstant;
import com.mysoft.framework.core.common.spring.SpringContextHolder;
import com.mysoft.framework.core.function.authorization.GenerateUserHelper;
import com.mysoft.framework.core.function.strategy.Strategy;
import com.mysoft.framework.dataprovider.function.application.MyOpenIdentityService;
import com.mysoft.framework.dataprovider.function.application.UserService;
import com.mysoft.framework.dataprovider.function.dto.MyOpenApiIdentityDTO;
import com.mysoft.framework.dataprovider.function.dto.UserEntityDTO;
import com.mysoft.framework.mvc.common.exception.AuthenticationException;
import com.mysoft.framework.mvc.function.authentication.processor.AppAuthenticationProcessor;
import com.mysoft.gfyx.common.constants.AuthConstant;
import com.mysoft.gfyx.workbench.service.dto.UserCodeTokenDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.file.AccessDeniedException;
import java.util.List;

import static java.lang.Boolean.TRUE;

@Strategy(values = AuthConstant.AUTH_PROCESSOR_NAME, order = AuthConstant.AUTH_PROCESSOR_ORDER)
@Slf4j
public class SpecificUserAuthenticationProcessor extends AppAuthenticationProcessor {

    @Autowired
    private CacheProvider cacheProvider;


    @Autowired
    private ObjectProvider<MyOpenIdentityService> myOpenIdentityService;

    @Override
    public boolean support(HttpServletRequest request) {
        // System.out.println("-----------------------------支持--------------------");
        // System.out.println(StringUtils.isNotEmpty(request.getHeader(AuthConstant.TOKEN_FIELD)));
        return StringUtils.isNotEmpty(request.getHeader(AuthConstant.TOKEN_FIELD));
    }

    @Override
    public boolean check(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader(AuthConstant.TOKEN_FIELD);
        String userCode = "";

        try {
            userCode = doCheck(token);
        } catch (YcgAuthenticationException e) {
            throw new AuthenticationException("认证失败：" + e.getMessage());
        }

        if (StringUtils.isBlank(userCode)) {
            return false;
        } else {
            UserService userService = SpringContextHolder.getBean(UserService.class);
            List<UserEntityDTO> userByCode = userService.findUserByCode(userCode);
            if (userByCode == null || userByCode.size() == 0) {
                throw new AuthenticationException("token所存储的用户Code：" + userCode + "不存在，请检查环境配置");
            }
            UserEntityDTO userDTO = userByCode.get(0);
            GenerateUserHelper.generateUserOfUserIntegration(request, userDTO);
        }

        return true;
    }

    /**
     * 进行认证
     *
     * @param token
     * @return
     */
    private String doCheck(String token) throws YcgAuthenticationException {

        if (StringUtils.isBlank(token) ) {
            throw new YcgAuthenticationException("pub接口需要在header传递token字段：" + AuthConstant.TOKEN_FIELD);
        }

        try {
            // 拼接缓存的key
            String cacheKey = AuthConstant.TOKEN_PREFIX + token;

            UserCodeTokenDto userCodeTokenDto = cacheProvider.get(cacheKey);

            if (userCodeTokenDto == null) {
                throw new YcgAuthenticationException("Token不存在，请检查Token是否正确或者过期");
            }

            return userCodeTokenDto.getUserCode();

        } catch (Exception e) {
            log.error("pub接口认证失败!", e);
            throw new YcgAuthenticationException("pub接口认证失败!");
        }
    }
}